package com.example.autopia.view.Activities

import android.app.Dialog
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.animation.AnimationUtils
import android.widget.ImageButton
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.example.autopia.R
import com.example.autopia.databinding.ActivityParkingBinding
import com.example.autopia.model.Item.Car
import com.example.autopia.model.Item.Parking
import com.example.autopia.model.Item.Place
import com.example.autopia.model.Item.Transaction
import com.example.autopia.model.Item.User
import com.example.autopia.model.Item.ViewPlace
import com.example.autopia.model.Repositories.ParkingRepository
import com.example.autopia.model.Repositories.TransactionRepository
import com.example.autopia.model.Repositories.UsersRepository
import com.example.autopia.utilities.TimeManager
import com.example.autopia.utilities.TimerCollection
import com.example.autopia.view.Adapters.CarItemAdapter
import com.example.autopia.view.Adapters.ColorItemAdapter
import com.example.autopia.view.Listeners.CarItemListener
import com.example.autopia.view.customview.PlaceView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase

class ParkingActivity : AppCompatActivity() {
    private lateinit var binding: ActivityParkingBinding

    //Репозитории
    private val repository = ParkingRepository()
    private val userRepository = UsersRepository()
    private val transactionRepository = TransactionRepository()

    //Вспомогающие классы
    private val firebaseAuth = Firebase.auth
    private val timeMamager = TimeManager()
    private val myTimer = TimerCollection()

    //Переменные
    private var parkingId: String? = "0"
    private lateinit var parking: Parking
    private lateinit var user: User
    private val views = ArrayList<ViewPlace>()
    private var isBlock: Boolean = false
    private var isHold: Boolean = false
    private lateinit var car: Car

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityParkingBinding.inflate(layoutInflater)
        setContentView(binding.root)
        myTimer.cancelTimer()
        //Выезд парковок
        startAnimations()
        //Как выглядит нижнее меню
        bottomSheet()
        //Получение id парковки
        parkingId = intent.extras?.getString("parkingId")
        userRepository.getUserById(firebaseAuth.currentUser?.uid ?: "").observe(this) {
            user = it
            if (user.carsList != null) {
                car = user.carsList!!.get(0)
                binding.tvCar.text = car.model + " - " + car.number
                binding.tvCar.setOnClickListener { showDialogChoiceCar() }
            } else {
                Toast.makeText(this@ParkingActivity, "Добавьте автомобиль", Toast.LENGTH_SHORT).show()
            }
            //Все что нужно после получения парковки
            if (parkingId != null) {
                repository.getParkingById(parkingId!!).observe(this) { it ->
                    parking = it
                    setParkData()
                    setDefault()
                    setListeners()
                    updaterPlaces(parking.id)
                }
            }
        }
        binding.ibBack.setOnClickListener {
            finish()
        }
    }

    //Автоматическое обновление мест
    private fun updaterPlaces(parkingId: String) {
       repository.updaterPlaces(parkingId).observe(this) {
            parking = it
            setParkData()
            setDefault()
            setListeners()
        }
    }
    private fun setListeners() {
        for (place in views) {
            val view = findViewById<PlaceView>(place.resources)
            view.setOnClickListener(null)
            if (place.place.status == 0) {
                view.setOnClickListener { v ->
                    val animation = AnimationUtils.loadAnimation(this, R.anim.slide_and_fade_to_top)
                    setDefault()
                    if (place.place.id.contains("A")) {
                        v.setBackgroundResource(R.drawable.place_background_active_right_side)
                    }
                    if (place.place.id.contains("B")) {
                        v.setBackgroundResource(R.drawable.place_background_active_left_side)
                    }
                    v as PlaceView
                    v.text = ""
                    binding.tvPlace.text = "Место - " + place.place.id
                    binding.tvNamePark.text = parking.name
                    binding.tvAddress.text = parking.address
                    binding.sheet.visibility = View.VISIBLE
                    binding.sheet.startAnimation(animation)
                    if (!isBlock) {
                        binding.btBlock.setOnClickListener {
                            binding.Buttons.visibility = View.VISIBLE
                            place.place.status = 2
                            place.place.car = car
                            place.place.userId = user.id
                            repository.changePlace(parking.id, place.place.id, place.place)
                            val trans = Transaction(
                                "1",
                                place.place,
                                parking.name,
                                parking.id,
                                true,
                                parking.price,
                                timeMamager.getCurrentUnixTime(),
                                timeMamager.getTimeWithFiveMins(),
                            )
                            transactionRepository.addTransaction(trans)
                            isBlock = true
                            binding.sheet.visibility = View.GONE

                            binding.Timer.setOnClickListener {
                                isHold = true
                                place.place.status = 1
                                trans.startTime = timeMamager.getCurrentUnixTime()
                                trans.endTime = 0
                                repository.changePlace(parking.id, place.place.id, place.place)
                                transactionRepository.changeTransaction(trans.id, trans)
                                binding.Timer.visibility = View.INVISIBLE
                                myTimer.cancelTimer()
                            }
                        }
                    } else {
                        binding.flChangerCar.visibility = View.GONE
                        binding.labelCar.visibility = View.GONE
                        binding.Buttons.visibility = View.GONE
                    }
                }
            }
        }
    }
    private fun setDefault() {
        for (place in views) {
            val view = findViewById<PlaceView>(place.resources)
            view.setBackgroundResource(getBackground(place.place, place.place.id))
            if (place.place.userId == user.id && place.place.status == 2) {
                isBlock = true
                val res = transactionRepository.getTransactionByPlace(place.place, parking.id, user.id)
                res.observe(this) { trans ->
                    if (trans.place!!.status == 2) {
                        binding.Timer.setOnClickListener {
                            isHold = true
                            trans.place!!.status = 1
                            trans.startTime = timeMamager.getCurrentUnixTime()
                            trans.endTime = 0
                            repository.changePlace(parking.id, trans.place.id, trans.place)
                            transactionRepository.changeTransaction(trans.id, trans)
                            binding.Timer.visibility = View.INVISIBLE
                            myTimer.cancelTimer()
                        }
                        myTimer.cancelTimer()
                        startTimer(place.place, timeMamager.getCurrentUnixTime(), trans.endTime, trans)
                    }
                }
            } else if (place.place.status == 2) {
                val res = transactionRepository.getTransactionByPlace(place.place, parking.id, place.place.userId)
                res.observe(this) { trans ->
                    if (trans.endTime <= timeMamager.getCurrentUnixTime() && trans.place!!.status == 2) {
                        place.place.status = 0
                        place.place.userId = "nothing"
                        transactionRepository.removeTransaction(trans.id)
                        repository.changePlace(parking.id, place.place.id, place.place)
                    }
                }
            }
            if (place.place.status == 1 || place.place.status == 2 || place.place.status == 4) {
                view.text = ""
            } else {
                view.text = place.place.id
            }
        }
    }
    private fun setParkData() {
        val resources = resources
        for (place in parking.placeList!!) {
            views.add(ViewPlace(place, resources.getIdentifier(place.id, "id", packageName)))
        }
        binding.tvParkingName.text = parking.name
        binding.loading.visibility = View.GONE
    }
    private fun startTimer(place: Place, startTime: Int, endTime: Int, transaction: Transaction) {
        binding.Timer.visibility = View.VISIBLE
        binding.Timer.startAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_and_fade_to_bot))
        binding.tvTimerPlace.text = "Место - " + place.id

        myTimer.startTimer(startTime.toLong(), endTime.toLong(), object : TimerCollection.TimerListener {
            override fun onTimerTick(millisUntilFinished: Long) {
                binding.tvTimer.text = timeMamager.formatMilliseconds(millisUntilFinished)
            }
            override fun onTimerFinish() {
                Log.d("Yatoro",isHold.toString()+ " " +isBlock.toString())
                if (!isHold) {
                    Log.d("Yatoro","Заходит")
                    binding.Timer.visibility = View.GONE
                    place.status = 0
                    place.car = null
                    place.userId = "nothing"
                    isBlock = false
                    transactionRepository.removeTransaction(transaction.id)
                    repository.changePlace(parking.id, place.id, place)
                    binding.Timer.setOnClickListener { }
                }
            }
        })
    }
    private fun getBackground(place: Place, id: String): Int {
        var res = 0
        when (place.status) {
            0 -> {
                res = if (id.contains("A")) {
                    R.drawable.place_background_empty_right_side
                } else {
                    R.drawable.place_background_empty_left_side
                }
            }
            1 -> {
                res = if (place.userId == user.id) {
                    isHold = true
                    isBlock = true
                    if (id.contains("A")) {
                        R.drawable.place_background_my_hold_right_side
                    } else {
                        R.drawable.place_background_my_hold_left_side
                    }
                } else {
                    if (id.contains("A")) {
                        R.drawable.place_background_hold_right_side
                    } else {
                        R.drawable.place_background_hold_left_side
                    }
                }
            }
            2 -> {
                res = if (place.userId == user.id) {
                    if (id.contains("A")) {
                        R.drawable.place_background_wait_right_side
                    } else {
                        R.drawable.place_background_wait_left_side
                    }
                } else {
                    if (id.contains("A")) {
                        R.drawable.place_background_busy_right_side
                    } else {
                        R.drawable.place_background_busy_left_side
                    }
                }
            }
            4 -> {
                res = if (id.contains("A")) {
                    R.drawable.place_background_broken_right_side
                } else {
                    R.drawable.place_background_broken_left_side
                }
            }
        }
        return res
    }
    private fun bottomSheet() {
        BottomSheetBehavior.from(binding.sheet).apply {
            peekHeight = 125
            this.state = BottomSheetBehavior.STATE_EXPANDED
        }
    }
    private fun startAnimations() {
        var animation = AnimationUtils.loadAnimation(this, R.anim.slide_and_fade_to_right)
        binding.rightSide.startAnimation(animation)
        animation = AnimationUtils.loadAnimation(this, R.anim.slide_and_fade_to_left)
        binding.leftSide.startAnimation(animation)
    }
    private fun showDialogChoiceCar() {
        val dialog = Dialog(this@ParkingActivity)
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(R.layout.dialog_choise_color)

        val rec = dialog.findViewById<RecyclerView>(R.id.ColorList)
        val btClose = dialog.findViewById<ImageButton>(R.id.btClose)

        val adapter = CarItemAdapter()
        rec.adapter = adapter
        if (!user.carsList.isNullOrEmpty()) {
            adapter.setData(user.carsList!!)
        }
        adapter.attachListener(object : CarItemListener {
            override fun onCarItemClicked(car: Car) {
                this@ParkingActivity.car = car
                binding.tvCar.text =
                    this@ParkingActivity.car.model + " - " + this@ParkingActivity.car.number
                dialog.dismiss()
            }
        })
        btClose.setOnClickListener {
            dialog.dismiss()
        }
        dialog.show()
        dialog.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.window?.attributes!!.windowAnimations = R.style.DialogAnimation
        dialog.window?.setGravity(Gravity.BOTTOM)
    }
}
